﻿using RuoVea.ExIdGen.Contract;
using RuoVea.ExIdGen.Core;
using System;
using System.Threading;

namespace RuoVea.ExIdGen
{
    /// <summary>
    /// 标识Id生成
    /// </summary>
    public class IdGenerator : ConfigureOption
    {
        /// <summary>
        /// 
        /// </summary>
        public static IIdGenerator IdGenInstance => _IdGenInstance;

        /// <summary>
        /// 生成新的Id
        /// 调用本方法前，请确保调用了 SetIdGenerator 方法做初始化。
        /// 否则将会初始化一个WorkerId为1的对象。
        /// </summary>
        /// <returns></returns>
        private static long NextId()
        {
            if (_IdGenInstance == null)
            {
                _IdGenInstance = new DefaultIdGenerator(new IdGeneratorOptions() { WorkerId = 0 });
            }
            return _IdGenInstance.NewLong();
        }

        #region 自动生成编号
        private static int _sn = 0;
        private static readonly object Locker = new object();
        /// <summary>
        /// 自动生成编号  201008251145409865
        /// </summary>
        /// <returns></returns>
        public static string No()
        {
            lock (Locker)  //lock 关键字可确保当一个线程位于代码的临界区时，另一个线程不会进入该临界区。
            {
                if (_sn == int.MaxValue) _sn = 0; else _sn++;
                Thread.Sleep(10);
                Random random = new Random();
                string strRandom = random.Next(1000, 10000).ToString(); //生成编号
                string code = DateTime.Now.ToString("MMHHmmyyyyssdd") + strRandom;//形如
                return code;
            }
        }
        #endregion

        /// <summary>
        /// 生成 数值型 Id
        /// </summary>
        /// <returns></returns>
        public static long Id
        {
            get
            {
                return NextId();
            }
        }

        /// <summary>
        /// 生成 字符串 Id
        /// </summary>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public static string IdStr(string prefix = "")
        {
            return prefix + NextId();
        }
    }
}